package com.dcd.controller;

import com.alibaba.fastjson.JSON;
import com.dcd.annotation.MultiRequestBody;
import com.dcd.pojo.User;
import com.dcd.pojo.WxMaUserInfo;
import com.dcd.pojo.WxTemp;
import com.dcd.service.UserService;
import com.dcd.util.AesUtil;
import com.dcd.util.JsonUtil;
import com.dcd.util.VerificationCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/UserController")
public class UserController {

    @Autowired
    private AesUtil aesUtil;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private VerificationCodeUtil verificationCodeUtil;

    /**
     * 登录
     *
     * @param user 用户对象 token 标识唯一用户，判断登录用户
     * @return
     */
    @RequestMapping("/login")
    public String login(@MultiRequestBody("user") User user, @MultiRequestBody("token") String token, @CookieValue(value = "cookie_user", required = false) Cookie cookie_user, HttpServletResponse response) throws Exception {
        if (token != null && token.trim().length() != 0) {
            try {
                token = aesUtil.decrypt(token);// 解密
            } catch (Exception e) {
                return "{\"result\":\"token_false\"}";
            }
        }
        Object redis_token = redisTemplate.opsForValue().get(token);//已保存在redis中的token
        if (redisTemplate.opsForValue().get(user.getUser_phone()) != null) {//用户已在线
            if (redis_token == null || !redis_token.toString().equals(user.getUser_phone()))
                return "{\"result\":\"on_line\"}";
        }
        if (redis_token == null) {//未登录，没有token
            token = aesUtil.encrypt(UUID.randomUUID().toString()).substring(5, 15);//生成token
        }
        /*用户端已发放非伪造token*/
        if (user.getUser_password() != null)/*账密登录*/
            user.setUser_password(aesUtil.encrypt(user.getUser_password()));
        /*没有在线，直接登录*/
        User result = userService.login(user);
        if (result != null) {//登录成功
            /*cookie*/
            add_cookie("cookie_user", JSON.toJSONString(result), cookie_user, response);
            add_cookie("cookie_token", aesUtil.encrypt(token), cookie_user, response);
            /*登录的不是原本的账号，则删除原本redis中的数据*/
            if (redis_token != null && !redis_token.toString().equals(user.getUser_phone())) {
                redisTemplate.delete(redis_token);//删除redis中原本的手机号
            }
            redisTemplate.opsForValue().set(user.getUser_phone(), result, 600, TimeUnit.SECONDS);//保存用户信息，标记该用户名已在线
            redisTemplate.opsForValue().set(token, user.getUser_phone(), 600, TimeUnit.SECONDS);//标记登录用户已登录
            //token = aesUtil.encrypt(token);/*二次加密*/
            return "{\"result\":\"login_true\"}";//给用户发放唯一token
        }
        return "{\"result\":\"login_false\"}";
    }

    /**
     * 微信登录回调
     *
     * @param body 主体信息
     * @return
     * @throws Exception
     */
    @RequestMapping("/we_chat_call_back")
    public String we_chat_call_back(@RequestBody String body) throws Exception {
        System.err.println(body);
        //把json转换为对象
        WxTemp wxTemp = JsonUtil.jsonToObject(body, WxTemp.class);
        String nick_name = wxTemp.getWxMaUserInfo().getNickName();
        if (wxTemp != null) {
            //根据用户名查询redis-->已在线
            if (redisTemplate.opsForValue().get(nick_name) != null) {
                redisTemplate.opsForValue().set(wxTemp.getTempUserId(), "we_chat_on_line", 59, TimeUnit.SECONDS);
                return "{\"code\":\"1\",\"msg\":\"用户已在线,请稍后再试!\"}";
            }
            //生成token
            String token = aesUtil.encrypt(UUID.randomUUID().toString()).substring(5, 15);
            // 保存用户token信息-->标记已登录
            redisTemplate.opsForValue().set(wxTemp.getTempUserId(), token, 59, TimeUnit.SECONDS);
            // 保存用户nick_name信息-->标记已在线
            redisTemplate.opsForValue().set(token, nick_name, 600, TimeUnit.SECONDS);
            //保存登录用户信息
            redisTemplate.opsForValue().set(nick_name, wxTemp.getWxMaUserInfo(), 600, TimeUnit.SECONDS);
            //"code": "0:登录成功；其他：登录失败","msg": "响应给用户的提示信息，该信息用于在小程序端进行提示"
            return "{\"code\":\"0\",\"msg\":\"登陆成功!\"}";
        }
        redisTemplate.opsForValue().set(wxTemp.getTempUserId(), "we_chat_login_false", 59, TimeUnit.SECONDS);
        return "{\"code\":\"1\",\"msg\":\"登录失败!\"}";
    }

    /**
     * 前台指定时间判断是否微信已登录
     *
     * @param temp_user_id 用户临时id
     * @return
     * @throws Exception
     */
    @RequestMapping("/we_chat_check_whether_login/{temp_user_id}")
    public String we_chat_check_whether_login(@PathVariable String temp_user_id, @CookieValue(value = "cookie_user", required = false) Cookie cookie_user, HttpServletResponse response) throws Exception {
        Object result = redisTemplate.opsForValue().get(temp_user_id);
        if (result != null) {
            if (result.equals("we_chat_on_line")) {
                return "{\"result\":\"we_chat_on_line\"}";
            } else if (result.equals("we_chat_login_false")) {
                return "{\"result\":\"we_chat_login_false\"}";
            }
            Object nick_name = redisTemplate.opsForValue().get(result);
            Object wx_user = redisTemplate.opsForValue().get(nick_name);
            if (nick_name != null && wx_user instanceof WxMaUserInfo) {
                WxMaUserInfo wx_user_info = (WxMaUserInfo) redisTemplate.opsForValue().get(nick_name);
                //添加用户到数据库
                User user = new User(0, wx_user_info.getNickName(), null, null, wx_user_info.getAvatarUrl(), "暂无简介", new Date());
                //没有保存在数据库
                if (userService.select_we_chat_whether_add(user.getUser_name()).indexOf("false") != -1) {
                    user.setUser_register_date(new Date());
                    user.setUser_personal_signature("个人简介暂无消息");
                    Map<String, Object> map = userService.add_we_chat_user(user);
                    user = JsonUtil.jsonToObject(JSON.toJSONString(map.get("user")), User.class);
                } else if (true) {//已存在-->根据用户名查询
                    user = userService.select_user_by_user_name(user.getUser_name());
                }
                //重新保存登录用户信息(数据库用户)
                redisTemplate.opsForValue().set(nick_name, user, 600, TimeUnit.SECONDS);
                /*cookie*/
                add_cookie("cookie_user", JSON.toJSONString(user), cookie_user, response);
                add_cookie("cookie_token", aesUtil.encrypt(result.toString()), cookie_user, response);
            }
            //给用户发放加密token
            return "{\"result\":\"we_chat_login_true\"}";
        }
        return "{\"result\":\"no_login\"}";
    }

    /**
     * 发送短信返回验证码
     *
     * @return
     */
    @RequestMapping("/get_verification_code")
    public String get_verification_code() {
        return "{\"verification_code\":\"" + verificationCodeUtil.send_verification_code() + "\"}";
    }

    /**
     * 注册
     *
     * @param user 用户对象 js传入json格式
     * @return
     */
    @RequestMapping("/register")
    public String register(@RequestBody User user) throws Exception {
        String result_phone = userService.select_phone_whether_register(user.getUser_phone());
        if (result_phone.indexOf("true") != -1) return result_phone;//手机号已被注册
        user.setUser_password(aesUtil.encrypt(user.getUser_password()));
        user.setUser_name(UUID.randomUUID().toString().substring(0, 10));//随机生成用户姓名
        user.setUser_head_portrait_url("default_user_head_portrait.jpg");//默认用户头像
        user.setUser_register_date(new Date());
        user.setUser_personal_signature("个人简介暂无消息");
        return userService.register(user);
    }

    /**
     * 查询指定用户信息
     *
     * @param token 用户唯一标识token
     * @return
     */
    @RequestMapping("/get_user_mess/{token}")
    public Object get_user_mess(@PathVariable String token) {
        Object result = null;
        try {
            result = redisTemplate.opsForValue().get(aesUtil.decrypt(token));
            if (result == null)
                return "{\"result\":\"token_false\"}";
        } catch (Exception e) {
            return "{\"result\":\"token_false\"}";
        }
        if (result != null) {
            return redisTemplate.opsForValue().get(result);
        }
        return null;
    }

    /**
     * 退出登录
     *
     * @param token 用户唯一标识token
     */
    @RequestMapping("/exit_login/{token}")
    public String exit_login(@PathVariable String token, @CookieValue(value = "cookie_user", required = false) Cookie cookie_user, HttpServletResponse response) {
        try {
            cookie_user = new Cookie("cookie_user",
                    URLEncoder.encode("", "utf-8"));
            cookie_user.setMaxAge(0);/*0s*/
            cookie_user.setPath("/");
            response.addCookie(cookie_user);
            token = aesUtil.decrypt(token);
            Object phone = redisTemplate.opsForValue().get(token);
            redisTemplate.delete(phone);
            redisTemplate.delete(token);
        } catch (Exception e) {
        }
        return "{\"result\":\"true\"}";
    }

    /**
     * 根据用户id查询视频集合
     *
     * @param user_id 用户id  y
     * @param
     * @return
     */
    @RequestMapping("/select_videoList_byUserId/{user_id}/{pageindex}")
    public Map<String, Object> select_videoList_byUserId(@PathVariable Integer user_id, @PathVariable Integer pageindex) {
        return userService.select_videoList_byUserId(user_id, pageindex);
    }

    /**
     * 根据用户id查询所有发布的资讯
     *
     * @param user_id 用户id
     * @return
     */
    @RequestMapping("/select_information_byUserId/{user_id}/{pageIndex}")
    public Map<String, Object> select_information_byUserId(@PathVariable Integer user_id, @PathVariable Integer pageIndex) {
        return userService.select_information_byUserId(user_id, pageIndex);
    }

    /**
     * 检查该粉丝是否存在
     *
     * @param user_id       用户登录的id  y
     * @param cover_user_id 粉丝的id
     * @return
     */
    @RequestMapping("/existsFenSi/{user_id}/{cover_user_id}")
    public int existsFenSi(@PathVariable Integer user_id, @PathVariable Integer cover_user_id) {
        return userService.existsFenSi(user_id, cover_user_id);
    }

    /**
     * 检查是否有发布视频
     * @param user_id
     * @return
     */
    @RequestMapping("/existsSelect_videoList_byUserId/{user_id}")
    public int existsSelect_videoList_byUserId(@PathVariable Integer user_id){
         return userService.existsSelect_videoList_byUserId(user_id);
    }

    /**
     * 检查是否有发布资讯
     * @param user_id
     * @return
     */
    @RequestMapping("/existsSelect_information_byUserId/{user_id}")
    public int existsSelect_information_byUserId(@PathVariable Integer user_id){
        return userService.existsSelect_information_byUserId(user_id);
    }

    @RequestMapping("/existsVideo_and_Information/{user_id}")
    public Map<String,Object> existsVideo_and_Information(@PathVariable Integer user_id){
        Map<String,Object> map=new HashMap<String, Object>();
        map.put("existsVideo",userService.existsSelect_videoList_byUserId(user_id));
        map.put("exixtsInformation",userService.existsSelect_information_byUserId(user_id));
        return map;
    }

    /**
     * 登录后添加cookie
     *
     * @param value       cookie值
     * @param cookie_user
     * @param response
     * @throws UnsupportedEncodingException
     */
    private void add_cookie(String name, String value, Cookie cookie_user, HttpServletResponse response) throws UnsupportedEncodingException {
        /*用户id*用户头像*token*/
        cookie_user = new Cookie(name,
                URLEncoder.encode(value, "utf-8"));
        cookie_user.setMaxAge(600);/*600s*/
        cookie_user.setPath("/");
        response.addCookie(cookie_user);
    }
}
